package com.lz.yz.member.web;


import com.lz.yz.base.common.ValidatorUtil;
import com.lz.yz.base.entity.ReturnValue;
import com.lz.yz.base.exception.InvalidArgumentException;
import com.lz.yz.base.exception.UnauthorizedException;
import com.lz.yz.base.util.Constant;
import com.lz.yz.member.entity.Account;
import com.lz.yz.member.entity.Member;
import com.lz.yz.member.enumeration.AccountField;
import com.lz.yz.member.enumeration.AccountType;
import com.lz.yz.member.group.ThirdLoginGroup;
import com.lz.yz.member.model.AccountModel;
import com.lz.yz.member.model.ResponseAccount;
import com.lz.yz.member.model.ThirdLoginModel;
import com.lz.yz.member.service.AccountService;
import com.lz.yz.member.service.MemberService;
import com.lz.yz.outing.service.SmsService;
import com.lz.yz.outing.util.SmsMessage;
import com.util.common.ValidateHelper;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

@RestController
public class LoginController {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    HttpServletRequest request;

    @Autowired
    AccountService accountService;

    @Autowired
    SmsService smsService;

    @Autowired
    MemberService memberService;

    @Resource(name = "redisTemplate")
    RedisTemplate<String, Integer> redisTemplate;


    /**
     * 根据手机号请求发送短信验证码 绑定手机
     * @param phone 手机号
     * @return 结果
     */
    @ApiOperation(value="绑定手机发送短信验证码",response = ReturnValue.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "手机号", dataType = "Integer", paramType = "path")
    })
    @GetMapping("/user/band/sendSMS/{phone}")
    public ReturnValue sendBandSMSByPhone(@PathVariable String phone) {
        // 判断手机号
        if (ValidatorUtil.validatePhoneNum(phone)) {
            if (memberService.validateAccount(phone)) {
                return ReturnValue.generateFalseReturnValue("手机号已绑定过,不能重复绑定！");
            }
            String validateCode=smsService.generateValidateCode();
            if (smsService.sendSyncSms(new SmsMessage(phone,validateCode, Constant.BAND_PHONE_TEMPLATE_CODE))) {
                return ReturnValue.generateTrueReturnValue("验证码发送成功！");
            }
        } else {
            return ReturnValue.generateFalseReturnValue("请填写正确的手机号！");
        }
        return ReturnValue.generateFalseReturnValue("发送短信验证码接口异常");
    }

    /**
     * 绑定手机号
     * @param phone 手机号
     * @return 结果
     */
    @ApiOperation(value="绑定手机号",response = ReturnValue.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "手机号", dataType = "String", paramType = "path"),
            @ApiImplicitParam(name = "validCode", value = "验证码", dataType = "String", paramType = "path"),
            @ApiImplicitParam(paramType = "header",name = "Authorization",value = "Bearer token",defaultValue = "Bearer ")
    })
    @PostMapping("/user/{phone}/{validCode}")
    public ReturnValue sendDoLoginSMSByPhone(@PathVariable String phone,@PathVariable String validCode) throws IllegalAccessException, NoSuchFieldException, InstantiationException {
        Integer accountId = accountService.getAccountIdByRequest(request);
        if (ValidatorUtil.validatePhoneNum(phone)) {
            if(smsService.validCode(phone,validCode)){
                accountService.updateByIdSelective(new Account(accountId,phone));
                Member member=memberService.findBy("accountId",accountId);
                memberService.update(new Member(member.getId(),phone));
                return ReturnValue.generateTrueReturnValue("绑定成功!");
            }else {
                return ReturnValue.generateFalseReturnValue("验证码错误！");
            }

        }else {
            return ReturnValue.generateFalseReturnValue("请填写正确的手机号！");
        }
    }




    /**
     * 第三方登录
     * @param loginModel 第三方登录信息
     */
    @ApiOperation(value="第三方登录",response = ReturnValue.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "loginModel", value = "第三方登录实体", dataType = "ThirdLoginModel", paramType = "body"),
    })
    @PostMapping(value = "/user/oAuthLogin")
    public ReturnValue oAuthLoginSearch(@Validated({ThirdLoginGroup.class}) @RequestBody ThirdLoginModel loginModel, BindingResult result) throws Exception{
        String errorMsg = ValidateHelper.firstErrorMessage(result);
        if (errorMsg != null) {
            throw new InvalidArgumentException(errorMsg);
        }
        return memberService.validateAndRegist(loginModel);
    }


    /**
     * 刷新token
     *
     * @return 返回有效的token
     */
    @ApiOperation(value="刷新token",response = AccountModel.class)
    @PatchMapping("/auth/refreshToken")
    public ReturnValue refreshToken(@RequestBody AccountModel user) {
        String token = user.getToken();
        if (accountService.getAccountByField(AccountField.Token, token, AccountType.Internal.value()+"") == null) {
            throw new UnauthorizedException("无效账户的token");
        }
        Account loginAccount = accountService.doLogin(AccountField.Token, token, null, AccountType.Internal.value()+"");
        ResponseAccount model = new ResponseAccount(loginAccount.getId());
        BeanUtils.copyProperties(loginAccount, model);
        return ReturnValue.generateTrueReturnValue(model);
    }


    @ApiOperation(value="判断是否登陆过pc端(1登陆过0没登陆)",response = ReturnValue.class)
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header",name = "Authorization",value = "Bearer token",defaultValue = "Bearer ")
    })
    @GetMapping("/user/isLoginPc")
    public ReturnValue isLoginPc() {
        Integer accountId = accountService.getAccountIdByRequest(request);
        ValueOperations<String, Integer> ops = redisTemplate.opsForValue();
        return ReturnValue.generateTrueReturnValue(ops.get(Constant.PC_LOGIN_KEY + accountId)!=null);
    }

    @ApiOperation(value="退出登陆清空状态",response = ReturnValue.class)
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header",name = "Authorization",value = "Bearer token",defaultValue = "Bearer ")
    })
    @DeleteMapping("/user/loginPc")
    public ReturnValue deleteLoginStatus() {
        Integer accountId = accountService.getAccountIdByRequest(request);
        redisTemplate.delete(Constant.PC_LOGIN_KEY + accountId);
        return ReturnValue.generateTrueReturnValue();
    }
}
